
#include <string>
#include <rapidjson/writer.h>
#include <rapidjson/stringbuffer.h>
#include <rapidjson/document.h>
using namespace rapidjson;
using namespace std;

class JsonCpp
{
    typedef Writer<StringBuffer> JsonWriter;

public:
    JsonCpp() : m_writer(m_buf)
    {
    }

    ~JsonCpp()
    {
    }

    /**
	* 序列化结构体数组之前需调用此接口，然后再循环去Serialize
	*/
    void StartArray()
    {
        m_writer.StartArray();
    }

    /**
	* 序列化结构体数组之后需调用此接口，循环Serialize完成之后调用
	*/
    void EndArray()
    {
        m_writer.EndArray();
    }

    void StartObject()
    {
        m_writer.StartObject();
    }

    void EndObject()
    {
        m_writer.EndObject();
    }

    template <typename T>
    void WriteJson(string &key, T &&value)
    {
        m_writer.String(key.c_str());
        WriteValue(std::forward<T>(value));
    }

    template <typename T>
    void WriteJson(const char *key, T &&value)
    {
        m_writer.String(key);
        WriteValue(std::forward<T>(value));
    }

    ///**
    //* 返回对象序列化后端json字符串
    //*/
    const char *GetString() const
    {
        return m_buf.GetString();
    }

private:
    template <typename V>
    typename std::enable_if<std::is_same<V, int>::value>::type WriteValue(V value)
    {
        m_writer.Int(value);
    }

    template <typename V>
    typename std::enable_if<std::is_same<V, long unsigned int >::value>::type WriteValue(V value)
    {
        m_writer.Int(value);
    }

    template <typename V>
    typename std::enable_if<std::is_same<V, unsigned int>::value>::type WriteValue(V value)
    {
        m_writer.Uint(value);
    }

    template <typename V>
    typename std::enable_if<std::is_same<V, int64_t>::value>::type WriteValue(V value)
    {
        m_writer.Int64(value);
    }

    template <typename V>
    typename std::enable_if<std::is_floating_point<V>::value>::type WriteValue(V value)
    {
        m_writer.Double(value);
    }

    template <typename V>
    typename std::enable_if<std::is_same<V, bool>::value>::type WriteValue(V value)
    {
        m_writer.Bool(value);
    }

    template <typename V>
    typename std::enable_if<std::is_pointer<V>::value>::type WriteValue(V value)
    {
        m_writer.String(value);
    }

    template <typename V>
    typename std::enable_if<std::is_array<V>::value>::type WriteValue(V value)
    {
        m_writer.String(value);
    }

    template <typename V>
    typename std::enable_if<std::is_same<V, std::nullptr_t>::value>::type WriteValue(V value)
    {
        m_writer.Null();
    }

private:
    StringBuffer m_buf;  //json字符串的buf
    JsonWriter m_writer; //json写入器

    Document m_doc;
};
